use once_cell::sync::Lazy;
use rdev::{Event, EventType, listen};
use serde::Serialize;
use serde_json::{Value, json};
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, Instant};
use tauri::{AppHandle, Emitter, Runtime, command};

#[derive(Debug, Clone, Serialize)]
pub enum DeviceEventKind {
    MousePress,
    MouseRelease,
    MouseMove,
    KeyboardPress,
    KeyboardRelease,
}

#[derive(Debug, Clone, Serialize)]
pub struct DeviceEvent {
    kind: DeviceEventKind,
    value: Value,
}

static IS_LISTENING: AtomicBool = AtomicBool::new(false);

// 简单的鼠标移动事件节流：至少间隔 MOVE_MIN_MS 毫秒，且位移超过 MOVE_MIN_DELTA 才上报
const MOVE_MIN_MS: u64 = 16; // 约等于 60fps
const MOVE_MIN_DELTA: f64 = 1.0; // 像素阈值

static LAST_MOUSE_SAMPLE: Lazy<Mutex<(f64, f64, Instant)>> =
    Lazy::new(|| Mutex::new((f64::NAN, f64::NAN, Instant::now())));

#[command]
pub async fn start_device_listening<R: Runtime>(app_handle: AppHandle<R>) -> Result<(), String> {
    if IS_LISTENING.load(Ordering::Relaxed) {
        return Ok(());
    }

    IS_LISTENING.store(true, Ordering::Relaxed);

    let callback = move |event: Event| {
        let device_event = match event.event_type {
            EventType::ButtonPress(button) => {
                // 使用最近一次移动位置作为点击坐标
                let last = LAST_MOUSE_SAMPLE.lock().unwrap();
                let (last_x, last_y, _t) = *last;
                DeviceEvent {
                    kind: DeviceEventKind::MousePress,
                    value: json!({
                        "button": format!("{:?}", button),
                        "x": last_x,
                        "y": last_y,
                    }),
                }
            }
            EventType::ButtonRelease(button) => {
                let last = LAST_MOUSE_SAMPLE.lock().unwrap();
                let (last_x, last_y, _t) = *last;
                DeviceEvent {
                    kind: DeviceEventKind::MouseRelease,
                    value: json!({
                        "button": format!("{:?}", button),
                        "x": last_x,
                        "y": last_y,
                    }),
                }
            }
            EventType::MouseMove { x, y } => {
                // 节流判断
                let mut last = LAST_MOUSE_SAMPLE.lock().unwrap();
                let (last_x, last_y, last_t) = *last;
                let elapsed = last_t.elapsed();
                let dx = if last_x.is_nan() {
                    f64::INFINITY
                } else {
                    (x - last_x).abs()
                };
                let dy = if last_y.is_nan() {
                    f64::INFINITY
                } else {
                    (y - last_y).abs()
                };
                if elapsed < Duration::from_millis(MOVE_MIN_MS)
                    && dx < MOVE_MIN_DELTA
                    && dy < MOVE_MIN_DELTA
                {
                    // 丢弃过于频繁且位移过小的事件
                    return;
                }
                *last = (x, y, Instant::now());

                DeviceEvent {
                    kind: DeviceEventKind::MouseMove,
                    value: json!({ "x": x, "y": y }),
                }
            }
            EventType::KeyPress(key) => DeviceEvent {
                kind: DeviceEventKind::KeyboardPress,
                value: json!({ "key": format!("{:?}", key) }),
            },
            EventType::KeyRelease(key) => DeviceEvent {
                kind: DeviceEventKind::KeyboardRelease,
                value: json!({ "key": format!("{:?}", key) }),
            },
            _ => return,
        };

        let _ = app_handle.emit("device-changed", device_event);
    };

    listen(callback).map_err(|err| format!("Failed to listen device: {:?}", err))?;

    Ok(())
}
